use lazy_static::lazy_static;
use crate::kiss_fft::KissFFT;

pub(crate) const PI: f64=3.14159265358979323846264338327;
pub const FRAME_SIZE_SHIFT: i32 = 2;
pub const FRAME_SIZE: usize = 120<<FRAME_SIZE_SHIFT;

pub(crate) const WINDOW_SIZE: usize = (2*FRAME_SIZE);
pub(crate) const  FREQ_SIZE: usize = (FRAME_SIZE + 1);
pub(crate) const  NB_DELTA_CEPS: usize = 6;
pub(crate) const  NB_FEATURES: usize =  (NB_BANDS+3*NB_DELTA_CEPS+2);

// const  PITCH_MIN_PERIOD: i32 = 60;
pub const  PITCH_MAX_PERIOD: usize =  768;
pub const PITCH_FRAME_SIZE: usize =  960;
pub const PITCH_BUF_SIZE: usize = PITCH_MAX_PERIOD+PITCH_FRAME_SIZE;

pub const NB_BANDS: usize = 22;


pub(crate) struct Common{
    pub(crate) kiss_fft: KissFFT,
    pub(crate) half_window: [f32; FRAME_SIZE],
    dct_table:[f32; NB_BANDS*NB_BANDS],
}

impl Common {
    pub(crate) fn new() -> Self {
        let mut half_window: [f32; FRAME_SIZE] = [0.0; FRAME_SIZE];


        let mut dct_table: [f32; NB_BANDS*NB_BANDS] = [0.0; NB_BANDS*NB_BANDS];

        Common {
            kiss_fft: KissFFT::new(FRAME_SIZE),
            half_window,
            dct_table,
        }
    }

    fn init(&mut self) {
        let mut i: usize = 0;
        while i <FRAME_SIZE {
            self.half_window[i] = (0.5 * PI * ((0.5 * PI * (i as f64 + 0.5) / FRAME_SIZE as f64).sin()) * ((0.5 * PI * (i as f64 + 0.5) / FRAME_SIZE as f64).sin())).sin() as f32;
        }

        i = 0;
        while i < NB_BANDS {
            let mut j: usize = 0;
            while j < NB_BANDS {
                self.dct_table[i*NB_BANDS+j] = ((i as f64+0.5)*(j as f64)*PI/NB_BANDS as f64).cos() as f32;
                if (j==0) {
                    self.dct_table[i*NB_BANDS + j] *= 0.5_f32.sqrt();
                }
            }
        }
    }
}

lazy_static! {
    pub(crate) static ref COMMON:Common = Common::new();
}
// pub(crate) static COMMON:Common = Common::new();